[Omnibox] Kiến trúc
I. Tính năng
- Cho phép ứng dụng tích hợp với các CRM khác như Salesforce, Hubspot, Mobile App ...
II. Tổng quan kiến trúc
- Hiện tại Omnibox được tích hợp với các loại CRM, chia ra làm các nhóm sau :
Salesforce
- Mỗi tích hợp là một folder riêng
Hubspot
- Tất các các tích hợp Hubspot sử dụng chung template Hubspot
Các nhóm khác là default
- Tất cả các loại CRM khác
Mobile App
- Android
- Ios
1. Mô hình tích hợp vào các CRM
Khi người dùng mở CRM / Mobile App Omnibox sẽ được load theo cách sau:
- Mobile App ( ReactNative ) : Domain trong webview
- Đối với các CRM và Hubspot : Domain trong Chrome Ext
- Salesforce : Domain trong CRM
Whitelist cho domain ở Digital Ocean
Whitelabel cho domain ở Cloudflare R2, ngoài ra thông tin được config đến mobile service cũng được lưu ở CFR2
Tham khảo sơ đồ sau

2. Authentication
- Auth thông qua keycloak, sau khi nhận token từ keyload, token này sẽ được dùng để sử dụng API ở Mobile Service
- Sau khi Login thành công, các thông tin của User, CRM được gọi lên từ Mobile Service để xử lý như vị trí click2call hay bộ API, Iframe của mỗi tích hợp ( Xem DOC lần đầu tiên tích hợp)
Tham khảo sơ đồ sau ở mục Login và Auth, chuột phải + mở hình ở newtab cho dễ xem

- Tham khảo Gcalls Config, nơi config thông tin couchDB cho Omnibox
3. Luồng gọi Outbound và Inbound
3.1 Tích hợp
- Đường màu tím từ integrator thể hiện lifetime của tích hợp khi có cuộc gọi Inbound và Outbound
- Sau khi login thông tin của tích hợp bao gồm những thông tin được load lên iframe, hay các function cần xử lý riêng cho tích hợp sẽ được load lên và lưu lại tại Omnibox (Xem sơ đồ login).
- Đối với ReactNative, user sẽ mở app thông qua deeplink hay nhập phone number vào diapad để gọi
- Đối với CRM (Web), user sẽ sử dụng chrome extension
- Đối với Salesforce, domain của Omnibox được config trong CRM
3.2 Cuộc gọi Outbound
Nếu không thấy số hotline hiện trên Omnibox lúc gọi thì nhờ tel4 trả về bản tin SIP field hotline_outbound ở mục onMessage ( event của bản tin SIP), search keyword trong source Omnibox
- Xem sơ đồ ở phần cuộc gọi Outbound
3.2.1 - Sơ đồ

3.2.2 - Trường hợp SIP FAIL ( Mô tả sơ đồ)
- 1 . Khi Agent thực hiện 1 cuộc gọi, chúng ta không có cơ chế validate SIP trước. Đôi khi SIP Regis được nhưng không gọi được có thể do Hotline hết cước hay vì nguyên nhân nào đó từ phía PBX.
- 2 . Lúc này event được Pbx trả về là fail
- 3 . Hệ thống thực hiện lưu log đối với thông tin cuộc gọi hiện tại
- 4 . Theo sơ đồ thì luồng save calllog vào database của Gcalls và luồng save calllog vào CRM đang chạy song song, do đó có thể xảy ra các trường hợp mất log nếu yêu cầu savelog bị fail ở 1 trong 2. Và mất log thì mất luôn không backup được cho CRM do mỗi CRM config Obj calllog khác nhau thông qua logFuntion ở mục Info trong Integrator phía trên
- 5 . Phần sơ đồ maù vàng là saveLog vào couchDB phần này đang được phát triển để gom log lại 1 chỗ và xử lý tuần tự ở Raw Service . Nếu làm được phần này thì lợi ích là giữ lại được log CRM hay Log CRM ở CouchDB nếu lưu log fail và có thể dùng để backup . Thực hiện lưu tuần tự log CRM trước và log Gcalls sau do nếu saveLog vào CRM fail, mà log trong Gcalls có thì khách sẽ vào webphone thấy và thắc mắc. Hơn nữa, Log của CRM sẽ có nhiều thông tin khác so với log tiêu chuẩn
3.2.3 - Trường hợp SIP SUCCESS ( Mô tả sơ đồ)
Khi Agent thực hiện 1 cuộc gọi, Omnibox sẽ gửi thông tin thực hiện cuộc gọi đi đến PBX thông qua SDK, từ đây PBX nhận được yêu cầu và xử lý
1. Các trạng thái của cuộc gọi ( event)
Ở SDK có các event lắng nghe trạng thái cuộc gọi như outgoing(), progress() , confirm(), onTrack(), ended(), failed(). Các event này cũng được đưa xuống Omnibox để lấy thông tin từ các trạng thái và xử lý thêm nếu cần
- outgoing() : gửi tín hiệu outgoing đến PBx, để bên PBX kết nối cuộc gọi đến User
- progress() : lúc này bên phía điện thoại của User nhận được cuộc gọi mà chưa bắt máy ( RING RING RING)
- confirm() : khi user confirm() thì cuộc gọi sẽ được kết nối để 2 bên nói chuyện với nhau, lúc này PBX cũng trả về thông tin cho Omnibox vào mục event confirm() để biết (Usecase: lấy thời gian User bắt máy)
- onTrack() : Lúc này 2 bên đang nói chuyện với nhau thông qua peer2peer connection (Webview) , phần này có nối âm thanh 2 bên - code trong SDK
- ended() : Khi User không bắt máy, bấm endcall khi đang gọi, hay bấm endcall khi chưa bắt máy hoặc agent bấm endcall thì thông tin log sẽ được trả về event này
- failed() : Các trường hợp như user hông đóng cước, lỗi không thực hiện được cuộc gọi, SIP có vấn đề dẫn đến việc Agent thực hiện cuộc gọi không được thì thông tin cuộc gọi sẽ được trả về event failed()
2. Tham khảo sơ đồ Outbound Call ở phần SIP SUCCESS
Phần này mô tả 1 cuộc gọi đã kết nối thành công. Trong trường hợp User không bắt máy, hay Agent huỷ thì sẽ nhận được thông tin cuộc gọi thông qua event failed() hoặc ended() với status tương ứng
- 1 . Khi user bắt máy thì thông tin sẽ chuyển đến PBX xử lý. Omnibox sẽ nhận được thông tin trả về ở event confirm(), và event Ontrack(). Ở event ontrack() thực hiện xử lý đấu nối âm thanh tới User thông qua WebRTC - peer2peer connection
- 2 . Khi các bên như User hay Agent thực hiện hành động endcall(), thì thông tin Omnibox sẽ nhận được thông tin của calllog thông qua event ended(). Từ đây chúng ta có 1 log hoàn chỉnh và xử lý theo đúng cấu trúc hệ thống rồi tiến hành lưu
3.3 Cuộc gọi Inbound
Xem sơ đồ cuộc gọi Inbound
- 1 . User gọi vào số hotline của Agent
- 2 . Pbx tiếp nhận thông tin, và trả thông tin về cho Omnibox
- 3 . Agent nhận được thông tin Incoming ( ring ring ring)
- 4 . Agent Accept Call, thông tin được gửi đến Pbx xử lý
- 5 . Pbx xử lý và trả thông tin cuộc gọi về status on ontrack(), âm thanh 2 bên kết nối với nhau
- 6 . Khi 1 trong 2 endcall thì sẽ thực hiện lưu calllog
III. Cài đặt
- Clone project:
git clone https://gitlab.com/gcalls/publics/omnibox
- Change dir into userService folder to run backend
cd callbox
- Install utility modules:
npm run installpackage
IV. Những điều cần chú ý về việc saveLog, hạn chế mất log
1. Quy tắc saveLog
- Luồng saveLog phải đảm bảo lưu tuần tự: saveLog vào CRM ( các tích hợp) thành công rồi mới saveLog vào Database Gcalls. Lưu log vào Crm không thành công thì không lưu log vào Gcalls vì số lượng log ở Crm và Gcalls phải đồng bộ
2. Nhiệm vụ của couchDB, Logstash, Rawservice đối với luồng lưu log
Lưu ý : Log phải luôn được đi vô couchDB đầu tiên trước khi saveLog vào Gcalls hay CRM
- Bước 1 . Logstash có nhiệm vụ luôn lắng nghe những thay đổi về dữ liệu ở couchDB
- Bước 2 . Khi có 1 dữ liệu mới (calllog) được thêm vào couchDB, Logstash lắng nghe và lấy dữ liệu đó post vào Rawservice
- Bước 3 . Rawservice nhận calllog đó và thực hiện quy trình lưu log ( saveLogCrm thành công rồi mới saveLog vào DB Gcalls)
- Bước 4 . Nếu quy trình lưu calllog thành công, thực hiện xoá calllog ở couchDB

Log từ client là calllog-gcalls, log từ server là calllog system
V. WhiteLabel cho 1 domain khác ở Omnibox
1. Set up domain
Bước 1: Chọn Set up a custom domain, thêm vào sub domain của khách hàng

Bước 2: Thêm Sub domain và bấm continue

Bước 3: Chọn Begin Cname setup

Bước 4: Khách Cname theo thông tin của CF

Bước 5: Sau khi khách Cname xong, thấy domain của khách active là thành công

2. Set up Brand Identify
Bước 1: Vào Cloudflare R2, chọn bucket brand-identify

Bước 2: Tạo folder chứa các thông tin liên quan đến Brand Identify
Copy ra 1 folder với tên folder trùng với tên domain cần WhiteLabel

Bước 3: Tham khảo các folder khác và xin bộ brand-identify của khách và nối domain của khách vào folder trong file config.json(tải về thêm vào và reupload)
Phần này cần cơ chế quản lý thông tin được upload vào brand-identify, hiện tại đang upload manual
Tham khảo nội dung trong text (chứa text), color(màu sắc cần sử dụng) và images (chứa icon, favicon, background ...).

Bước 4: Whitelist cho domain của khách vào mobile-service
Xin khách subdomain dành cho mobile service và trỏ về server Nginx. Tham khảo nội dung config cho Mobile Service ở server chứa Nginx
VI. Deploy Day
- Nếu Prod day có deploy sdk, tham khảo Gcalls SDK
1. Friday
Đối với Friday deploy, Cloudflare Page đang tự động build sau khi được merge vào branch Test
Điểm mạnh : Luồng CI CD nhanh giúp kỹ sư không phải quan tâm đến vấn đề build và manual upload lên Cloudflare page
Điểm yếu : Khi build Omnibox với SDK ở branch dev hay test(trong giai đoạn dev sdk), lúc này sdk chưa được publish, nên khi Omnibox sử dụng npm i để install sdk sẽ không được . Không thể tự upload build folder lên để Test
2. Prod day
- Đối với Prod day hiện tại thực hiện manual upload
#copy .env from gcallsenv
git checkout Test
npm run installpackage
npm run build
Bước 1: Vào Cloudflare Page (callbox-prod)
Bước 2: Bấm vào Create New Deployment

Bước 3: Chọn Production

Bước 4: Upload build folder sau đó bấm Save and deploy
- Đối với PROD có thể config lại tự động deploy, trước khi deploy omnibox prod có thể deploy sdk trước